Перейти к основному содержимому

5.02. Знаки препинания

Разработчику Архитектору

Знаки препинания

Начнём с самого фундаментального отличия.

Если вы помните нашу главу по ООП, то запомнили синтаксис:

функция(параметры) { тело возврат };

Это Java, C#, JavaScript синтаксис, где блок кода ограничен { и }. Отступы и пробелы там — это стилистика, интерпретатор их игнорирует. Вот пример с Java:

void main() {
System.out.println("Hello World!");
}

В Python всё иначе, здесь нет никаких фигурных скобок и точек с запятой в блоках кода. Блок кода в Python определяется отступами (indentation).

Отступ (indent) - это табуляция, свободное пространство или отклонение от края колонки одной или нескольких строк (чтобы сделать отступ, надо нажать клавишу Tab).

def main():
print("Hello World!")
print("Second line")
print("Outside the function")

Обратите внимание - здесь четыре строки, где первая и последняя - на одном уровне, а вторая и третья - на уровень правее, то есть с одним отступом.

Строка def main(): — объявление функции. Следующие строки с одинаковым отступом (обычно 4 пробела) считаются частью тела функции. Когда отступ возвращается к предыдущему уровню — блок заканчивается.

То есть, print("Hello World!") и print("Second line") — внутри main, а print("Outside the function") — вне main, потому что нет отступа. Как мы помним, блок кода в классических языках имеет открывающие слова или скобки, и закрывающие. В Python закрывать блок не нужно, нет необходимости писать end, }, endif или что-то подобное. Конец блока определяется возвратом на предыдущий уровень отступа.

if x > 0:
print("Positive")
if x > 10:
print("Large positive")
print("Still in if")
print("After if")

Здесь print("Large positive") — вложенный блок (больший отступ), print("Still in if") — возврат на уровень if x > 0, а print("After if") — вне условия.

Рекомендация PEP 8: используй 4 пробела на уровень отступа. Старайтесь не смешивать пробелы и табуляции, иначе возникнет ошибка - IndentationError, если случайно поставить таб вместо пробелов, или неправильно выровнять.

Python считает, что код должен быть читаемым. Форматирование — не опция, а часть синтаксиса. Это исключает споры о стиле и делает код визуально однородным. Поэтому тут не схитришь, хоть и нужно быть внимательным к пробелам, а копирование из разных источников может сломать отступы.

Следующее, что бросится в глаза - нижние подчёркивания, «_»:

_logger = "internal logger"

В обычных функциях вроде def main(): подчёркиваний нет. Но в некоторых местах они появляются — и это не случайно. Вот как это работает:

_name - одно подчёркивание в начале, это соглашение, обозначающее «внутреннее использование», не для публичного API. Не приватно, просто сигнал разработчикам. __name (с двумя подчёркиваниями) - name mangling, уже часть синтаксиса, Python переименовывает это поле, чтобы избежать случайного доступа из подклассов (чтобы не было конфликтов имён в наследованиях):

class MyClass:
def __init__(self):
self.__private = 42 # станет _MyClass__private

При компиляции имя переименовывается: __private → _MyClass__private.

class Parent:
def __init__(self):
self.__x = 10

class Child(Parent):
def __init__(self):
super().__init__()
self.__x = 20 # Это НЕ перезапишет Parent.__x

У Parent будет _Parent__x = 10, а у Child будет _Child__x = 20. Конфликта имён нет.

__name__ (с двух сторон) - магические методы / дандер-методы (синтаксис), используются интерпретатором для перегрузки операций:

def __init__(self): ...
def __str__(self): ...

Эти имена зарезервированы интерпретатором, а называются dunder от double underscore. Используются для перегрузки операций +, len(), str() и т.д.

_ может использоваться для «отбрасывания значения», означая переменную, которую мы не используем.

for _ in range(5):  # _ — переменная, которую мы не используем
print("Hello")

x, _, z = (1, 2, 3) # игнорируем второй элемент

Здесь _ — легальное имя переменной. Сигнал: "я знаю, что тут что-то есть, но мне это не нужно".

_ также используется как разделитель в числах:

million = 1_000_000
binary = 0b_1010_0001

Это полностью игнорируется интерпретатором и улучшает читаемость больших чисел.

Два важных вопроса, которые мучают начинающих программистов:

  1. Когда использовать кавычки двойные ("), одинарные ('), а когда апострофы ()?
  2. Когда использовать точки (.), запятые (,) и точку с запятой (;)?

Можно использовать оба типа кавычек:

name = "John"
message = 'Hello!'

Удобно использовать один тип внутри другого:

sentence = "He's a programmer"
quote = '"Hello!", she said'

Тройные кавычки для многострочных строк:

doc = """This is
a multi-line string."""

Апострофы () — не используются в синтаксисе Python, но могут быть частью строк. Точка (.) : используется для доступа к атрибутам и методам:

import math
print(math.pi)

Запятая (,) : разделяет элементы в списках, кортежах, аргументах функций:

nums = [1, 2, 3]
def greet(name, age): ...

Python не требует точку с запятой в конце строк. То есть, такой код будет вполне рабочим:

x = 5
y = 10
print(x + y)

Точка с запятой (;) : допускается для записи нескольких строк в одной строке кода:

x = 5; y = 10; print(x + y)

Но это не рекомендуется в боевом коде — снижает читаемость.

В Python символ «|» используется как побитовое ИЛИ, но с небольшим важным уточнением - в этом языке нет «||». Используется слово or - «ИЛИ».

Теперь о комментариях. Они в Python только однострочные по своей природе, но с ньюансом. Чтобы установить однострочный комментарий, нужно поставить # (решётку) перед текстом:

# Это комментарий
x = 5 # Это тоже комментарий

Всё после # до конца строки - комментарий. Нельзя делать «внутри строки», если она в кавычках.

В Python нет синтаксиса, как у других, вроде /* ... */. Но есть два способа сделать многострочные комментарии.

Первый - несколько строк с #, как бы просто не звучало:

# Это
# многострочный
# комментарий

Второй - строка документации (docstring) — """..."""

"""
Это не комментарий, а docstring.
Он сохраняется в атрибуте __doc__ и используется help().
"""

def greet(name):
"""
Приветствует пользователя.

Args:
name (str): имя пользователя
"""
print(f"Hello, {name}!")

Если тройные кавычки стоят в начале функции, класса, модуля — это docstring, а не комментарий. Он не игнорируется — хранится в памяти и доступен через help(). Поэтому правильно будет использовать именно несколько строк с #.

Двоичные (или побитовые) операторы работают с целыми числами на уровне их двоичного представления. Они применяются в задачах низкоуровневой обработки данных, шифрования, сетевых протоколов, оптимизации и флагов.

  • & - битовое И (AND). 1 если оба бита равны 1;
  • | - битовое ИЛИ (OR). 1 если хотя бы один бит равен 1;
  • ^ - исключающее ИЛИ (XOR). 1 если биты различаются;
  • ~ - инверсия (NOT). Заменяет 0 на 1 и наоборот;
  • << - сдвиг влево. Умножение на степень двойки;
  • >> - сдвиг вправо. Целочисленное деление на степень двойки.

Примеры:

a = 6   # 110 в двоичной системе
b = 3 # 011

print(a & b) # 2 → 010 (AND)
print(a | b) # 7 → 111 (OR)
print(a ^ b) # 5 → 101 (XOR)
print(~a) # -7 → инверсия с учётом дополнительного кода
print(a << 1) # 12 → 1100 (умножение на 2)
print(a >> 1) # 3 → 011 (деление на 2)

Использование побитовых операций ради «оптимизации» в обычном коде часто снижает читаемость. Применяйте их только там, где это оправдано (например, работа с аппаратными регистрами, сериализация, алгоритмы).

Экранированные последовательности — специальные комбинации символов, начинающиеся с обратного слеша \, которые интерпретируются как один символ или управляющий код.

  • \\ - сам обратный слеш
  • \' - одинарная кавычка
  • \" - двойная кавычка
  • \n - перевод строки (LF)
  • \r - возврат каретки (CR)
  • \t - горизонтальная табуляция
  • \b - backspace
  • \f - подача страницы (form feed)
  • \ooo - символ по восьмеричному коду
  • \xhh - символ по шестнадцатеричному
  • \uXXXX - Юникод-символ (16 бит)
  • \UXXXXXXXX - Юникод-символ (32 бита)

Примеры:

text = "Он сказал: \"Привет!\"\nИ ушёл."
path = "C:\\Users\\John\\Documents"

# Табуляция и перевод строки
formatted = "Имя:\tАлексей\nВозраст:\t30"

# Шестнадцатеричный код (латинская 'A' — 0x41)
char_a = '\x41' # → 'A'

# Юникод
smile = '\U0001F600' # 😄

Для отключения экранирования используется префикс r:

path = r"C:\Users\John\Documents"  # Обратные слеши не интерпретируются
regex = r"\d+\.\d+" # Регулярные выражения без экранирования

Тройные кавычки позволяют писать многострочные строки без \n:

doc = """Это
многострочный
текст."""

Но если нужно вставить кавычки:

quote = """Он сказал: "Мир прекрасен.""""